package p5sameWord;

import org.apache.lucene.analysis.TokenFilter;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
import org.apache.lucene.util.AttributeSource;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

/**
 * 定义自己的过滤器(这里是同义词过滤器)
 * 既然要过滤同义词，就要取出分词信息如下
 *
 */
final public class MySameWordTokenFilter extends TokenFilter{
    private CharTermAttribute cta=null;
    private PositionIncrementAttribute pia=null;
    //保存同义词的一些状态
    private AttributeSource.State current;
    /**
     * 这里是用一个变量sames保存，可以直接创建一个接口类，然后再这里引用
     * 比如SameWordContext,这个参数可以通过构造方法传进去
     *
     */
    //private SameWordContext sameWordContext;
    private Stack<String> sames;

    protected MySameWordTokenFilter(TokenStream input) {

        super(input);
        cta=this.addAttribute(CharTermAttribute.class);
        pia=this.addAttribute(PositionIncrementAttribute.class);
        sames=new Stack<>();
    }

    /**
     * 这个方法就相当于 analyzer 中的tokenStream的调用链，每一个tokenstream都会调用
     * 用于得到下一个Token。(相当于跳到下一分词)
     *
     * 敏感词也可以从这里过滤
     */
    public boolean incrementToken() throws IOException {

        while(sames.size()>0){

            //将元素出栈 并且获取这个同义词
            String str=sames.pop();
            //把状态还原回去，
            restoreState(current);
            //一个偏移量位置能放多个词？下面是输出
            //  1:china[15-20]--->word
            //  china
            //  0:tianchao[15-20]--->word
            //  tianchao
            cta.setEmpty();
            cta.append(str);
            //设置位置增长为0
            pia.setPositionIncrement(0);
            return true;

        }

        if(! input.incrementToken()){
            return false;
        }
        //进行同义词的处理判断
        if(getSameWord(cta.toString())){
            //如果有同义词的话 保存当前状态
            current=captureState();
        }
        return true;
    }

    public boolean getSameWord(String name){
        Map<String,String[]> map=new HashMap<>();
        //map.put("china",new String[]{"dalu","tianchao"});
        //map.put("henan",new String[]{"henan1","henan2"});
        map.put("i",new String[]{"my"});
        String [] sws=map.get(name);
        if(sws !=null){
            for(String str:sws){
                sames.push(str);
            }
            return true;
        }
        return false;

    }
}
